<template>
  <div class="card tree-filter">
    <h4 v-if="title" class="title sle">
      {{ title }}
    </h4>
    <el-input v-model="filterText" :placeholder="_transitionLanguages('placeholder', 'pleaseEnterASearchPhrase')" clearable />
    <el-scrollbar :style="{ height: title ? `calc(100% - 95px)` : `calc(100% - 56px)` }">
      <el-tree
        ref="treeRef"
        :node-key="id"
        v-bind="$attrs"
        :data="data"
        :highlight-current="true"
        :props="defaultProps"
        :filter-node-method="filterNode"
        @node-click="handleNodeClick"
      >
        <template #default="scope">
          <span class="el-tree-node__label">
            <slot :row="scope">
              {{ scope.node.label }}
            </slot>
          </span>
        </template>
      </el-tree>
    </el-scrollbar>
  </div>
</template>

<script setup lang="ts" name="TreeFilter">
import { ElTree } from 'element-plus';
// 语言转换
const _transitionLanguages = (v: string, l: string): string => {
  return transitionLanguages(v, l);
};
// 接收父组件参数并设置默认值
interface TreeFilterProps {
  requestApi?: (data?: any) => Promise<any>; // 请求分类数据的 api ==> 非必传
  data?: { [key: string]: any }[]; // 分类数据，如果有分类数据，则不会执行 api 请求 ==> 非必传
  title?: string; // treeFilter 标题 ==> 非必传
  id?: string; // 选择的id ==> 非必传，默认为 “id”
  label?: string; // 显示的label ==> 非必传，默认为 “label”
}
const props = withDefaults(defineProps<TreeFilterProps>(), {
  id: 'id',
  label: 'label'
});

const defaultProps = {
  children: 'children',
  label: props.label,
  isLeaf: 'leaf'
};

const treeRef = ref<InstanceType<typeof ElTree>>();
const treeData = ref<{ [key: string]: any }[]>([]);
const treeAllData = ref<{ [key: string]: any }[]>([]);
onBeforeMount(async () => {
  if (props.requestApi) {
    const data = await props.requestApi!();
    treeData.value = data;
    treeAllData.value = [{ id: '', [props.label]: '全部' }, ...data];
  }
});

watch(
  () => props.data,
  () => {
    if (props.data?.length) {
      treeData.value = props.data;
      treeAllData.value = [{ id: '', [props.label]: '全部' }, ...props.data];
    }
  },
  { deep: true, immediate: true }
);

const filterText = ref('');
watch(filterText, val => {
  treeRef.value!.filter(val);
});

// 过滤
const filterNode = (value: string, data: { [key: string]: any }, node: any) => {
  if (!value) return true;
  let parentNode = node.parent,
    labels = [node.label],
    level = 1;
  while (level < node.level) {
    labels = [...labels, parentNode.label];
    parentNode = parentNode.parent;
    level++;
  }
  return labels.some(label => label.indexOf(value) !== -1);
};
// emit
const emit = defineEmits<{
  change: [value: any];
}>();
// 单选
const handleNodeClick = (data: { [key: string]: any }) => {
  emit('change', data);
};
// 暴露给父组件使用
defineExpose({ treeData, treeAllData, treeRef });
</script>

<style scoped lang="scss">
@import './index.scss';
</style>
